#!/usr/bin/env python
# -*- coding: utf-8 -*-
# @Time    : 2024/4/22 11:03
# @File    : ui.py
# @Description : -i http://pypi.tuna.tsinghua.edu.cn/simple/ --trusted-host pypi.tuna.tsinghua.edu.cn

# https://www.emojiall.com/

import warnings

import math
import time
import numpy as np
import tkinter as tk
import ttkbootstrap as ttk
from ttkbootstrap.constants import *
from tkinter.filedialog import askdirectory, askopenfilename
from tksheet import Sheet
from pandas import DataFrame
from ttkbootstrap.dialogs import Querybox, Messagebox
from random import choice
from pathlib import Path

warnings.filterwarnings("ignore")
#PATH = Path(__file__).parent / 'assets'
import cv2


def change_style():
    brisk = cv2.BRISK_create()
    print(brisk)

    style = ttk.Style()
    theme = choice(style.theme_names())
    print(theme)
    style.theme_use(theme)


class AppUi(ttk.Frame):

    def __init__(self, master=None, **kwargs):
        super().__init__(master, **kwargs)
        self.master = master

        self.path = ttk.StringVar()
        self.ld_path = ttk.StringVar()
        self.apk_path = ttk.StringVar()
        self.thread_num = ttk.IntVar()
        self.cpu_num = ttk.IntVar()
        self.memory_num = ttk.StringVar()
        self.fbl_x_num = ttk.IntVar() # 分辨率
        self.fbl_y_num = ttk.IntVar() # 分辨率
        self.fbl_z_num = ttk.IntVar() # 分辨率
        self.target_value = ttk.IntVar()
        self.actual_value = ttk.IntVar()
        self.runing = ttk.IntVar()
        self.runing.set(0)
        self.thread_num.set(1)
        self.cpu_num.set(1)
        self.memory_num.set(1024)
        self.fbl_x_num.set(1024)
        self.fbl_y_num.set(860)
        self.fbl_z_num.set(30)
        self.target_value.set(100)
        self.actual_value.set(98)

        image_files = {
            'play': 'icons8_play_24px.png',
            'play-light': 'icons8_play_24px_1.png',
            'refresh': 'icons8_refresh_24px.png',
            'star': 'icons8_star_24px.png',
            'stop-dark': 'icons8_stop_24px.png',
            'stop-light': 'icons8_stop_24px_1.png',
            'opened-folder': 'icons8_opened_folder_24px.png',
            'cancel': 'icons8_cancel_24px_1.png',
            'file': 'icons8_file_24px.png',
            'download': 'icons8_downloads_folder_40px.png',
            'logo': '1.png'
        }

        self.photoimages = []
        imgpath = Path(__file__).parent / 'static'
        for key, val in image_files.items():
            _path = imgpath / val
            self.photoimages.append(ttk.PhotoImage(name=key, file=_path))

        self.pack(fill=ttk.BOTH, expand=ttk.YES)
        # 头部
        self.top = ttk.Frame(self, bootstyle="primary", height=20)
        self.top.pack(fill=ttk.X, side=ttk.TOP)

        # btn = ttk.Label(master=self.top, text="途游首充助手", bootstyle=('primary', 'inverse'))
        # btn.pack(side=LEFT, ipadx=1, ipady=1, padx=0, pady=1)

        btn = ttk.Button(master=self.top, text="主题切换", command=change_style)
        btn.pack(side=RIGHT, ipadx=1, ipady=1, padx=0, pady=1)
        # 内容
        self.div = ttk.Frame(self, bootstyle="warning")
        self.div.pack(fill=ttk.BOTH, expand=ttk.YES, side=ttk.TOP)

        self.body = ttk.Panedwindow(self.div, orient='horizontal')
        self.body.pack(fill=ttk.BOTH, expand=ttk.YES, side=ttk.TOP)

        self.sidebar = ttk.Frame(self.body, bootstyle="secondary", height=20, width=245)
        self.sidebar.pack(side=ttk.LEFT, fill=ttk.BOTH, expand=ttk.YES, )
        self.show_sidebar()

        self.body_canvas = ttk.Panedwindow(self.body, orient='vertical', width=560)
        self.body_canvas.pack(fill=ttk.BOTH, expand=ttk.YES, side=ttk.RIGHT)

        self.body.add(self.sidebar)
        self.body.add(self.body_canvas)

        self.tb = self.init_table(self.body_canvas)
        self.log_text = self.init_log(self.body_canvas)

        self.body_canvas.add(self.tb)
        self.body_canvas.add(self.log_text)

        # 底部
        self.bottom = ttk.Frame(self, bootstyle="light", height=20)
        self.bottom.pack(fill=ttk.X, side=ttk.BOTTOM)

    def show_sidebar(self):
        master = self.sidebar
        lbl = ttk.Labelframe(
            master=master,
            text='路径配置',
            bootstyle='dark',
            # width=240,
            height=200
        )
        lbl.pack(padx=1, pady=0, fill=ttk.BOTH, side=TOP)
        dev_info_body = ttk.Frame(lbl)
        dev_info_body.pack(fill=ttk.BOTH, expand=ttk.YES)
        self.create_get_file(dev_info_body)
        self.create_get_apk(dev_info_body)
        self.create_get_ld_path(dev_info_body)

        ld_settings = ttk.Labelframe(
            master=master,
            text='启动配置',
            bootstyle='dark',
        )
        ld_settings.pack(padx=1, pady=1, fill=ttk.BOTH, expand=ttk.YES, side=TOP)
        self.create_thread_num(ld_settings)
        self.create_ld_settings(ld_settings)


    def create_get_file(self, master):
        container = ttk.Frame(master)
        container.pack(fill=X,  pady=5, side=TOP)
        lbl = ttk.Label(master=container, text="卡密：", width=0)
        lbl.pack(side=LEFT, padx=(1, 0))
        ent = ttk.Entry(master=container, textvariable=self.path, font='Arial 8 bold')
        ent.insert(tk.END, '输入文件路径')
        ent.pack(side=LEFT, padx=1, pady=1, fill=X, expand=YES)
        btn = ttk.Button(
            master=container,
            image='opened-folder',
            # text=":",
            bootstyle=(LINK, SECONDARY),
            compound=LEFT,
            command=self.get_file_path
        )
        btn.pack(side=LEFT, ipadx=0, ipady=0, padx=(1, 0), pady=1)

    def create_get_apk(self, master):
        container = ttk.Frame(master)
        container.pack(fill=X,  pady=5, side=TOP)
        lbl = ttk.Label(master=container, text="APK：", width=0)
        lbl.pack(side=LEFT, padx=(1, 0))
        ent = ttk.Entry(master=container, textvariable=self.apk_path, font='Arial 8 bold')
        ent.insert(tk.END, '输入APK路径')
        ent.pack(side=LEFT, padx=1, pady=1, fill=X, expand=YES)
        btn = ttk.Button(
            master=container,
            image='opened-folder',
            # text=":",
            bootstyle=(LINK, SECONDARY),
            compound=LEFT,
            command=self.get_file_path
        )
        btn.pack(side=LEFT, ipadx=0, ipady=0, padx=(1, 0), pady=1)

    def create_get_ld_path(self, master):
        container = ttk.Frame(master)
        container.pack(fill=X,  pady=5, side=TOP)
        lbl = ttk.Label(master=container, text="雷电：", width=0)
        lbl.pack(side=LEFT, padx=(1, 0))
        ent = ttk.Entry(master=container, textvariable=self.ld_path, font='Arial 8 bold')
        ent.insert(tk.END, '输入雷电路径')
        ent.pack(side=LEFT, padx=1, pady=1, fill=X, expand=YES)
        btn = ttk.Button(
            master=container,
            image='opened-folder',
            # text=":",
            bootstyle=(LINK, SECONDARY),
            compound=LEFT,
            command=self.get_directory
        )
        btn.pack(side=LEFT, ipadx=0, ipady=0, padx=(1, 0), pady=1)

    def create_thread_num(self, master):
        container = ttk.Frame(master)
        container.pack(fill=X,  pady=5, side=TOP)
        lbl = ttk.Label(master=container, text="多开数量：", width=0)
        lbl.pack(side=LEFT, padx=(1, 0))
        pb = ttk.Scale(
            master=container,
            orient=ttk.HORIZONTAL,
            from_=1,
            to=10,
            length=100,
            command=lambda x: self.thread_num.set(self.thread_num.get()),
            variable=self.thread_num
        )
        pb.pack(side=LEFT, padx=(1, 5), pady=1, fill=tk.X)
        ent = ttk.Entry(master=container, textvariable=self.thread_num, font='Arial 8 bold', width=5)
        ent.pack(side=LEFT, padx=(5, 1), pady=1)

    def create_ld_settings(self, master):
        """
            排列/启动/暂停/继续， cpu，内存， 分辨率，导出已完成，导出未完成
        """
        container = ttk.Frame(master)
        container.pack(fill=X,  pady=5, side=TOP)
        cpu_label = ttk.Label(master=container, text="CPU：", width=0)
        cpu_label.pack(side=LEFT, padx=(1, 0))
        cpu_ent = ttk.Entry(master=container, textvariable=self.cpu_num, font='Arial 8 bold', width=8)
        cpu_ent.pack(side=LEFT, padx=(5, 1), pady=1, )
        mm_label = ttk.Label(master=container, text="内存：", width=0)
        mm_label.pack(side=LEFT, padx=(5, 0))
        mm_ent = ttk.Entry(master=container, textvariable=self.memory_num, font='Arial 8 bold', width=8)
        mm_ent.pack(side=LEFT, padx=(5, 1), pady=1, )
        container2 = ttk.Frame(master)
        container2.pack(fill=X,  pady=5, side=TOP)
        fbx_label = ttk.Label(master=container2, text="分辨率：", width=0)
        fbx_label.pack(side=LEFT, padx=(1, 0))
        fbx_x_ent = ttk.Entry(master=container2, textvariable=self.fbl_x_num, font='Arial 8 bold', width=5)
        fbx_x_ent.pack(side=LEFT, padx=(3, 3), pady=1, )
        ttk.Label(master=container2, text="x", width=0).pack(side=LEFT)
        fbx_y_ent = ttk.Entry(master=container2, textvariable=self.fbl_y_num, font='Arial 8 bold', width=5)
        fbx_y_ent.pack(side=LEFT, padx=(3, 3), pady=1, )
        ttk.Label(master=container2, text="x", width=0).pack(side=LEFT)
        fbx_z_ent = ttk.Entry(master=container2, textvariable=self.fbl_z_num, font='Arial 8 bold', width=5)
        fbx_z_ent.pack(side=LEFT, padx=(3, 3), pady=1, )



        container4 = ttk.Frame(master, height=3, width=3)
        container4.pack(fill=X,  pady=5, side=TOP)
        sub_btn = ttk.Button(
            master=container4,
            text='排列模拟器',
            command=lambda: self.run_status(sub_btn),
            bootstyle=DEFAULT,
            #image="file",
            compound=LEFT,
            width=10,
        )
        sub_btn.pack(fill=BOTH,  ipadx=0, ipady=0, padx=(10, 10), pady=0, side=LEFT)
        sub_btn = ttk.Button(
            master=container4,
            text='关闭模拟器',
            command=lambda: self.run_status(sub_btn),
            bootstyle=DEFAULT,
            #image="file",
            compound=LEFT,
            width=10,
        )
        sub_btn.pack(fill=BOTH,  ipadx=0, ipady=0, padx=(10, 10), pady=0, side=LEFT)

        container5 = ttk.Frame(master, height=3, width=3)
        container5.pack(fill=X,  pady=5, side=BOTTOM)

        container6 = ttk.Frame(container5)
        container6.pack(fill=X,  pady=5, side=TOP)

        pb_label = ttk.Label(master=container6, text="进度：", width=0)
        pb_label.pack(side=LEFT, padx=(10, 0))
        pb = ttk.Progressbar(
            master=container6,
            maximum=self.target_value.get(),
            length=150,
            variable=self.target_value,
            bootstyle=("primary", 'striped'),  # striped 有条纹
            orient="horizontal"  # horizontal 水平， vertical 横向
        )
        pb.pack(padx=(0, 12), pady=1, side=LEFT)

        sub_btn = ttk.Button(
            master=container5,
            text='开始' if self.runing.get() == 0 else "停止",
            command=lambda: self.run_status(sub_btn),
            bootstyle=PRIMARY if self.runing.get() == 0 else WARNING,
            image='play-light' if self.runing.get() == 0 else "stop-light",
            compound=LEFT,
            width=5,
        )
        sub_btn.pack(fill=X,  ipadx=0, ipady=0, padx=(10, 10), pady=(10, 10))

        out_put_btn = ttk.Button(
            master=container5,
            text='导出结果',
            command=self.quit(),
            bootstyle=(LINK, DEFAULT),
            image="download",
            compound=LEFT,
        )
        out_put_btn.pack(fill=X,  ipadx=0, ipady=0, padx=(10, 10), pady=0)

        container3 = ttk.Frame(container5)
        container3.pack(fill=X,  pady=5, side=TOP)
        cb = ttk.Checkbutton(container3, text='完成后导出当前本地文件夹')
        cb.pack(padx=(40, 0), pady=5, fill=tk.BOTH)
        cb.invoke()

    def run_status(self, widget):
        self.runing.set(0) if self.runing.get() == 1 else self.runing.set(1)
        if self.target_value.get() != self.actual_value.get():
            if self.runing.get() == 0:
                text = "继续"
                color = WARNING
                image = "play-light"
                #self.actual_value.set(self.target_value.get())
            else:
                text = "停止"
                color = DANGER
                image = "stop-light"
        else:
            text = "完成"
            color = SUCCESS
            image = "star"

        widget.configure(
            bootstyle=color,
            image=image,
            text=text,
        )

    def on_submit(self):
        """Print the contents to console and return the values."""
        print("Name:", self.path.get())
        print("Address:", self.thread_num.get())
        Messagebox.ok(
            title='Button callback',
            message="OK"
        )
        return self.path.get(), self.thread_num.get()

    def on_cancel(self):
        """Cancel and close the application."""
        self.quit()

    def get_file_path(self):
        """Open dialogue to get directory and update variable"""
        self.update_idletasks()
        d = askopenfilename()
        if d:
            self.path.set(d)

    def get_directory(self):
        """Open dialogue to get directory and update variable"""
        self.update_idletasks()
        d = askdirectory()
        if d:
            self.ld_path.set(d)

    def create_form_entry(self, master, label, variable):

        """Create a single form entry"""
        container = ttk.Frame(master)
        container.pack(fill=X, expand=YES, pady=5)

        lbl = ttk.Label(master=container, text=label.title(), width=10)
        lbl.pack(side=LEFT, padx=5)

        ent = ttk.Entry(master=container, textvariable=variable)
        ent.pack(side=LEFT, padx=5, fill=X, expand=YES)

    def init_table(self, master):
        df = DataFrame(np.random.randint(0, 100, (30, 5)))
        df.reset_index(inplace=True)
        df.columns = ["编号"] + ["模拟器", "账号", "密码", "状态", "步骤"]
        tb = Table(master)
        tb.init_tab(df, 15)
        return tb

    def init_log(self, master):
        text = ttk.Text(master, font='helvetica 10 bold')
        text.configure(background="black", foreground='green')
        text.insert('end', '执行步骤记录信息......\n')
        text.insert('end', 'Hello, this is my text.\n')
        return text


class Table(ttk.Frame):

    def __init__(self,  *args, **kwargs):
        super().__init__(*args, **kwargs)
        self.data = DataFrame()
        self.current_page = 0
        self.page_size = 10
        self.pages = 1

        self.pack(fill=BOTH, expand=YES)

        self.tab_frame = ttk.Frame(self, style='primary.TFrame')
        self.tab_frame.pack(fill=BOTH, padx=2, pady=1, side=TOP)

        self.sheet = Sheet(self.tab_frame,
                           data=[[" " for _ in range(10)] for _ in range(10)])
        self.sheet.enable_bindings()
        self.sheet.pack(fill="both", expand=True)

        # self.page_frame = self.tab_frame
        self.page_frame = ttk.Frame(self)
        self.page_frame.pack(fill=X, pady=2, side=BOTTOM)

    def init_tab(self, data: DataFrame, page_size=10):
        self.data = data
        self.page_size = page_size
        self.pages = math.ceil(data.shape[0] / page_size)
        # 销毁旧部件
        self.sheet.destroy()
        self.sheet = Sheet(self.tab_frame,
                           width=500,
                           height=380,
                           #row_height=10,
                           column_width=100,
                           row_index_width=10,
                           show_x_scrollbar=False,
                           show_y_scrollbar=False,
                           show_top_left=False,
                           show_row_index=False,
                           align='c',
                           data=data.iloc[:page_size].values.tolist(),
                           headers=data.columns.tolist())
        self.sheet.enable_bindings()
        self.sheet.column_width(column=0, width=50, only_set_if_too_small=False, redraw=True)
        self.sheet.column_width(column=5, width=150, only_set_if_too_small=False, redraw=True)
        self.sheet.pack(fill="both", expand=True)
        # self.sheet.align_columns(columns=0, align="c")
        self.sheet.highlight_cells(row=1, column=1, bg='yellow', fg='red')
        # self.sheet.highlight_rows(rows=[1], bg='yellow', fg=None, highlight_index=True, redraw=True, end_of_screen=False,overwrite=True)
        # self.sheet.highlight_columns(columns=[1], bg='yellow', fg=None, highlight_header=True, redraw=True, overwrite=True)
        # self.sheet.dehighlight_all()
        self.sheet.bind("<Motion>", self.on_mouse_move)

        title = ttk.Button(
            master=self.page_frame,
            text=" 跳转 ",
            command=lambda :self.to_page(int(self.spn.get())-1)
        )
        title.pack(padx=1, pady=2, side=RIGHT)

        self.spn = ttk.Spinbox(self.page_frame, bootstyle="primary", from_=1, to=self.pages)
        self.spn.set(1)
        self.spn.pack(padx=5, pady=2, side=RIGHT)

        title = ttk.Label(
            master=self.page_frame,
            text=f" 共{self.pages}页 /",
            anchor=tk.CENTER
        )
        title.pack(padx=1, pady=2, side=RIGHT)

        title = ttk.Button(
            master=self.page_frame,
            text=" 上一页 ",
            command=self.last_page
        )
        title.pack(padx=5, pady=2, side=RIGHT)

        title = ttk.Button(
            master=self.page_frame,
            text=" 下一页 ",
            command=self.next_page

        )
        title.pack(padx=5, pady=2, side=RIGHT)

    def add_row(self, index, values: tuple):
        pass

    def delete_row(self, index):
        pass

    def next_page(self):
        index = self.page_size * (self.current_page+1)
        index_end = index+self.page_size
        current_data = self.data.iloc[index: index_end]
        if current_data.empty:
            Messagebox.show_warning("最后一页", position=(500, 500))
            return
        self.current_page += 1
        self.spn.set(self.current_page+1)
        self.sheet.set_sheet_data(data=current_data.values.tolist(),
                       reset_col_positions=True,
                       reset_row_positions=True,
                       redraw=True,
                       verify=False,
                       reset_highlights=False)

    def last_page(self):
        print(f"上一页:{self.current_page}")
        if self.current_page-1 == -1:
            Messagebox.show_warning("当前页为首页", position=(500, 500))
            return
        index = self.page_size * (self.current_page - 1)
        index_end = index+self.page_size
        print(f"开始：{index}, 结束：{index_end}")
        current_data = self.data.iloc[index: index_end]
        self.current_page -= 1
        self.spn.set(self.current_page+1)
        self.sheet.set_sheet_data(data=current_data.values.tolist(),
                       reset_col_positions=True,
                       reset_row_positions=True,
                       redraw=True,
                       verify=False,
                       reset_highlights=False)


    def to_page(self, page):
        print(page)
        if page > self.pages-1:
            Messagebox.show_warning("超出最大页数", position=(500, 500))
            return
        self.current_page = page
        self.spn.set(self.current_page+1)
        index = self.page_size * page
        index_end = index+self.page_size
        current_data = self.data.iloc[index: index_end]
        self.sheet.set_sheet_data(data=current_data.values.tolist(),
                       reset_col_positions=True,
                       reset_row_positions=True,
                       redraw=True,
                       verify=False,
                       reset_highlights=False)


    def on_mouse_move(self, event):
        # 获取鼠标在 tksheet 中的位置
        x, y = event.x, event.y
        # print(event.widget)
        # 每个单元格的宽高（这里默认认为每个单元格的宽高都一致）
        if self.sheet.get_row_heights().__len__() <=0: return
        row_wide = self.sheet.get_column_widths()[0]
        row_height = self.sheet.get_row_heights()[0]
        # 计算鼠标当前所在的行（注意要减去表头的高度，如果有的话）
        row, col = y // row_height, x // row_wide
        # print(row, col)
        # 检查行号是否在有效范围内
        if 0 <= row < self.sheet.get_row_heights().__len__():
            # 清除之前所有行的背景颜色
            self.sheet.dehighlight_rows(rows=[], redraw=True)
            # 为当前行加背景颜色
            self.sheet.highlight_rows(rows=[row], bg='#E6EFFD', fg=None)


if __name__ == '__main__':

    from tkinter import PhotoImage
    root = tk.Tk()
    root_width = 860
    root_height = 600
    root_x, root_y = 300, 50

    #root = ttk.Window("Data Entry", "flatly", size=(root_width, root_height), resizable=(False, False))
    #root.attributes('-fullscreen', 1)
    #root.iconbitmap("./static/favicon_cat.ico")
    icon = PhotoImage(file="./static/icons8_settings_24px.png")
    root.iconphoto(False, icon)
    root.title('--')
    root.geometry(f"{root_width}x{root_height}+{root_x}+{root_y}")

    AppUi(root)
    root.mainloop()